﻿
using CNative.Cloud.CPlatform.Diagnostics;
using CNative.Cloud.CPlatform.Messages;
using CNative.Cloud.CPlatform.Serialization;
using CNative.Cloud.CPlatform.Utilities;
using System;
using System.Collections.Concurrent;
using System.Text;
using CNativeEvents = CNative.Cloud.CPlatform.Diagnostics.DiagnosticListenerExtensions;

namespace CNative.Cloud.ProxyGenerator.Diagnostics
{
    public class RpcTransportDiagnosticProcessor : CPlatform.Diagnostics.Implementation.DefaultTransportDiagnosticProcessor
    {
        public RpcTransportDiagnosticProcessor(ITracingContext tracingContext, ISerializer<string> serializer)
            : base(tracingContext, serializer)
        {
            transportType = TransportType.Rpc;
        }

        [DiagnosticName(CNativeEvents.CNativeBeforeTransport, TransportType.Rpc)]
        public override void TransportBefore([Object] TransportEventData eventData)
        {
            var message = eventData.Message.GetContent<RemoteInvokeMessage>();
            var operationName = TransportOperationNameResolver(eventData);
            var context = _tracingContext.CreateEntrySegmentContext(operationName,
                new CPlatform.Diagnostics.Implementation.DefaultTransportCarrierHeaderCollection(eventData.Headers));
            if (!string.IsNullOrEmpty(eventData.TraceId))
                context.TraceId = ConvertUniqueId(eventData).ToString();
            context.Span.AddLog(LogEvent.Message($"Worker running at: {DateTime.Now}"));
            context.Span.SpanLayer = SpanLayer.RPC_FRAMEWORK;
            context.Span.Peer = new StringOrIntValue(eventData.RemoteAddress);
            context.Span.AddTag(Tags.RPC_METHOD, eventData.Method.ToString());
            context.Span.AddTag(Tags.RPC_PARAMETERS, _serializer.Serialize(message.Parameters));
            context.Span.AddTag(Tags.RPC_LOCAL_ADDRESS, NetUtils.GetHostAddress().ToString());
            _resultDictionary.TryAdd(eventData.OperationId.ToString(), context);
        }

        [DiagnosticName(CNativeEvents.CNativeAfterTransport, TransportType.Rpc)]
        public override void TransportAfter([Object] ReceiveEventData eventData)
        {
            base.TransportAfter(eventData);
        }

        [DiagnosticName(CNativeEvents.CNativeErrorTransport, TransportType.Rpc)]
        public override void TransportError([Object] TransportErrorEventData eventData)
        {
            base.TransportError(eventData);
        }
    }
}